<?php
/**
 * 21天减重测评算法
 * Created by PhpStorm.
 * User: liao
 * Date: 2016/12/12
 * Time: 16:41
 */

namespace App\Services\Result;

use App\Interf\Resultable;
use App\Models\LogHelper;
use Monolog\Logger;
use ParamConfig;



class WestMedicineResult extends BaseResult implements Resultable
{
    private $answers;

    private $relateConclusionIndex;

    private $relateTagMap;

    public function __construct($answersStr = null,$score = null)
    {
        $this->answers = $this->convertAnswer($answersStr);
        $this->heathStatusAttrObj = $this->configAttrObj(1,'健康状态');
        $this->heathAttentionAttrObj = $this->configAttrObj(2,'健康关注');
        $this->adviceAttrObj = $this->configAttrObj(3,'调养建议');
        $this->score = $score ? $score : 0;
        //相关的结论序号索引，结论有优先等级
        $this->relateConclusionIndex = [32,34,30];
        //相关的tag别名集合
        $this->relateTagMap = $this->relateTagMap();
    }


    public function result()
    {
        $attrs = [];
        /*健康状态*/
        array_push($attrs,$this->getHeathStatusAttrObj());
//        /**健康关注*/
        array_push($attrs,$this->getHeathAttentionAttrObj());
       /**调养建议*/
        array_push($attrs,$this->getAdviceAttrObj());
        //一下三个参数都是必须的
        $data['attrs'] = $attrs;
        $data['chatparam'] = $this->getChatparam();
        $data['chatType'] = $this->getChatType();
        return $data;

    }


    /**
     * 健康状态
     */
    protected function getHeathStatusAttrObj(){
        $note = '';
        //获取额外部分
        $extra = '';
        $this->getNoteByTagAlias($note,'health.status');
        $obj = $this->heathStatusAttrObj;
        $obj = $this->compactAttrObj($obj['attr_id'],$obj['title'],$note,$extra);
        return $obj;
    }
    /**
     * 健康关注
     */
    protected function getHeathAttentionAttrObj(){
        $note = '';
        //获取额外部分
        $extra = '';
        $this->getNoteByTagAlias($note,'health.attention');
        $obj = $this->heathAttentionAttrObj;
        $obj = $this->compactAttrObj($obj['attr_id'],$obj['title'],$note,$extra);
        return $obj;
    }


    /**
     * 专家解读部分
     */
    protected function getAdviceAttrObj(){
        $note = '';
        $this->getNoteByTagAlias($note,'advice');
        $obj = $this->adviceAttrObj;
        $obj = $this->compactAttrObj($obj['attr_id'],$obj['title'],$note);
        return $obj;
    }


    /**
     * 图标对应的BMI数据
     */
    protected function getChatparam(){
        $data = [];
        $obj['key'] = '健康分数';
        $obj['value'] = round(doubleval($this->score),2);
        array_push($data,$obj);
        return $data;
    }

    protected function getNoteByTagAlias(&$note,$tagAlias){
        if($tagAlias == 'health.status'){
            //健康状态
            $note .= $this->getHealthStatusResult();
        }else{
            $note .= $this->getTabValue($tagAlias);
        }
    }


    protected function getHealthStatusResult(){
        $data = '';
        $tagMaps = $this->relateTagMap;
        $healthStatusTag = $tagMaps['health.status'];
        $results = ParamConfig::getByTag($healthStatusTag);
        if(count($results)>0){
            foreach ($results as $result){
                //将分数代入表达式中进行计算
                if($this->getQuestionItemCondResult($result['key'],$this->score)){
                    $data = str_replace('${SCORE}',round(doubleval($this->score),2),$result['value']);
                    break;
                }
            }
        }
        return $data;
    }


    protected function getTabValue($tagAlias){
        $data = '';
        $tagMaps = $this->relateTagMap;
        if($tag = $tagMaps[$tagAlias]){
            $results = ParamConfig::getByTag($tag);
            if(count($results)>0){
                foreach ($this->relateConclusionIndex as $index){
                    foreach ($results as $k =>$result){
                        if($data = $this->getSingleItemVal($result,$index)){
                            break;
                        }
                    }
                    if($data){
                        break;
                    }
                }
                //如果结果都没法匹配，则直接使用默认的结果
                if(!$data){
                    $key = $tag.'.other';
                    $data = ParamConfig::getValue($key);
                }
            }

        }
        return $data;
    }

    /**
     * 获取单
     * #糖尿病|#32|health  形式为 ：　条件｜对应的题目索引值类型|tab类型
     * @35>=23|@35|health  形式为 ：　条件｜对应的题目索引值类型|tab类型
     * testing_param_config表中，key的形式为，$32=='糖尿病|$32|advice
     */
    private function getSingleItemVal($result,$index){
        $key = $result['key'];
        $kArr = explode('|',$key);
        $relateIndexContent = $kArr[1];
        $operate = substr($relateIndexContent,0,1);
        $answer = $this->getAnswerObjByIndex($this->answers,$index);
        $operateData =  '';
        if($operate == '#'){
            //这里因为$会被转义，所以采用#
            $operateData = $answer['answer'];
        }else if($operate == '@'){
            $operateData = $answer['weight'];
        }
        $expression = $kArr[0];
        $expOperate = substr($expression,0,1);
        $data = '';
        if($expOperate == '#'){
            //井号开头的表示是一个唯一值，此时需要跟答案进行比对
            $val = substr($expression,1);
            $multiAnswers = explode('|||',$operateData);
            if(in_array($val,$multiAnswers)){
                $data = $result['value'];
            }
        }else{
            $searchStr = $operate.$index;
            //替换@index或者$index的值，如 $32=='糖尿病 替换成 '高血压' == '糖尿病'
            if($searchStr == $relateIndexContent){
                $expression = str_replace($searchStr,$operateData,$expression);
                if($this->getQuestionItemCondResult($expression,$operateData)){
                    $data = $result['value'];
                }
            }

        }
        return $data;
    }


    private function relateTagMap(){
        return [
            'health.status' => 'TB.testing.west.result.health.stutus',
            'health.attention' => 'TB.testing.west.result.health.attension',
            'health.attention.other' => 'TB.testing.west.result.health.attension.other',
            'advice' => 'TB.testing.west.result.advice',
            'advice.other' => 'TB.testing.west.result.advice.other',
        ];
    }

}